package com.itheima.health.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.health.dao.MenuDao;
import com.itheima.health.entity.PageResult;
import com.itheima.health.entity.QueryPageBean;
import com.itheima.health.pojo.Menu;
import com.itheima.health.pojo.Role;
import com.itheima.health.pojo.User;
import com.itheima.health.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author by Dragon
 * @Classname MenuServiceImpl
 * @Description TODO
 * @Date 2020/2/23 13:16
 * @Version 1.0
 */
@Service
@Transactional
public class MenuServiceImpl implements MenuService {

    //菜单数据回显


    @Autowired
    private MenuDao menuDao;


    @Override
    public List<Menu> findMenuInfo() {
        return menuDao.findMenuInfo();
    }

    /**
     * @param user 登录的用户
     * @return Menu集合
     */
    @Override
    public List<Menu> getMenuByUser(User user) {
        //TODO 这里使用了权限框架容器的User对象，导致用户权限变更后不能即时更新
        //TODO 如果需要，可以增加实时性查询，牺牲性能换取安全性


        Set<Role> roles = user.getRoles();
        // (为了节省数据库查询次数，考虑到菜单集合不会很大) 所以一次先拿全，在服务层处理父子关系 而不是查询两次数据库

        List<Menu> allMenus = menuDao.getMenuByRoles(roles);
        //遍历总菜单集合 拿到菜单级别=1的集合 移动到父菜单集合
        List<Menu> fatherMenus = new ArrayList<>();
        for (Menu menu : allMenus) {
            if (menu.getLevel() == 1) {
                fatherMenus.add(menu);
            }
        }
        allMenus.removeAll(fatherMenus);
        //遍历父菜单集合 同时遍历剩余的菜单集合  如果上级单项的id和当前项的父id一致 则remove到上级项的子集中
        for (Menu fatherMenu : fatherMenus) {
            ArrayList<Menu> childrenMenus = new ArrayList<>();
            for (Menu menu : allMenus) {
                if (fatherMenu.getId().equals(menu.getParentMenuId())) {
                    childrenMenus.add(menu);
                }
            }
            fatherMenu.setChildren(childrenMenus);
        }
        //TODO 这里只针对菜单有两级的情况，如果菜单的级数不确定，需要优化
        return fatherMenus;
    }

    /*@Override
    public List<Menu> findParentMenu() {
        //获取父类菜单
        return menuDao.findParentMenu();
    }*/

    @Override
    public PageResult findParentMenu(QueryPageBean queryPageBean) {
        //设置分页插件初始参数
        PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        //通过Dao获取Page对象
        Page<Menu> parentMenus = menuDao.findParentMenuPage(queryPageBean.getQueryString());
        //2. 根据父菜单的id查询对应的子菜单
        for (Menu parentMenu : parentMenus) {
            List<Menu> childrenMenuList = findChildrenMenuByParentMenuId(parentMenu.getId());
            parentMenu.setChildren(childrenMenuList);
        }
        //通过Page对象，构建PageResult
        PageResult pageResult = new PageResult(parentMenus.getTotal(), parentMenus.getResult());

        return pageResult;
    }

    @Override
    public List<Menu> findChildrenMenuByParentMenuId(Integer id) {
        //查询子类菜单
        return menuDao.findChildrenMenuByParentMenuId(id);
    }

    @Override
    //获取父类弹出窗口
    public Menu findParentMenuById(Integer id) {
        return menuDao.findMenuById(id);
    }

    @Override
    //获取子类弹出窗口
    public Menu findChildrenMenuById(Integer id) {
        return menuDao.findMenuById(id);
    }

    @Override
    //添加父类菜单
    public Menu addParent(Menu parentMenu) {
        //查询所有父类菜单
        List<Menu> menuList = menuDao.findParentMenu();
        for (Menu menu : menuList) {
            if (menuList.size()!=0){
                System.out.println("添加成功");
            }
                if (parentMenu.getPriority().equals(menu.getPriority())){

                    System.out.println("优先级已存在请跟换");
                }
        }
        parentMenu.setPath(String.valueOf(parentMenu.getPriority() + 1));

        //2. set level
        parentMenu.setLevel(1);
        menuDao. addParent(parentMenu);
        return parentMenu;
    }

    //添加子类菜单
    @Override
    public void addChildren(Menu childrenMenu) {
        //查找对应的父类菜单
        Menu parentMenu = menuDao.findMenuById(childrenMenu.getParentMenuId());
        //根据父类查询所有子类
        List<Menu> menuList =  menuDao.findChildrenMenuByParentMenuId(parentMenu.getId());
            if (menuList.size()!=0){
                for (Menu menu : menuList) {
                    if (childrenMenu.getPriority().equals(menu.getPriority()));
                    System.out.println("优先级已存在请跟换");
                }
            }
            childrenMenu.setLevel(2);

        childrenMenu.setPath("/" + String.valueOf(parentMenu.getPriority() + 1) + "-" + String.valueOf(childrenMenu.getPriority()));
        menuDao.addParent(childrenMenu);
        }
    //删除父类菜单
    @Override
    public void delParentById(Integer id) {
        List<Menu> menuList =menuDao.findChildrenMenuByParentMenuId(id);
        if (menuList.size()!=0){
            throw new RuntimeException("父类菜单里有子类,请先删除子类");
        }
        menuDao.delById(id);
    }
    // 删除子类菜单
    @Override
    public void delChildrenById(Integer id) {
        menuDao.delById(id);
    }

    //编辑父类
    @Override
    @Transactional
    public void editParent(Menu parentMenu, int priorityInDB) {
        //1. 获取优先级

        int priorityInParam = parentMenu.getPriority();

        //2. 判断优先级是否发生变化
        if (priorityInDB == priorityInParam) {//未发生变化
            //edit
            menuDao.edit(parentMenu);
        } else if (priorityInDB > priorityInParam) {//优先级变小
            //查询所有的父菜单
            List<Menu> parentMenuList = menuDao.findParentMenu();
            for (Menu menu : parentMenuList) {
                //查询变化区间内的父菜单
                if (menu.getPriority() >= priorityInParam && menu.getPriority() < priorityInDB) {
                    //set priority
                    menu.setPriority(menu.getPriority() + 1);
                    //set path
                    menu.setPath(String.valueOf(menu.getPriority() + 1));
                    List<Menu> childrenMenuList = menuDao.findChildrenMenuByParentMenuId(menu.getId());
                    for (Menu childrenMenu : childrenMenuList) {
                        // set path
                        childrenMenu.setPath("/" + String.valueOf(menu.getPriority() + 1) + "-" + String.valueOf(childrenMenu.getPriority()));
                    }
                }
            }
            List<Menu> childrenMenus = menuDao.findChildrenMenuByParentMenuId(parentMenu.getId());
            for (Menu childrenMenu : childrenMenus) {
                // set path
                childrenMenu.setPath("/" + String.valueOf(parentMenu.getPriority() + 1) + "-" + String.valueOf(childrenMenu.getPriority()));
            }
            //set path
            parentMenu.setPath(String.valueOf(parentMenu.getPriority() + 1));
            //edit
            menuDao.edit(parentMenu);
        } else {//优先级变大
            //查询所有的父菜单
            List<Menu> parentMenuList = menuDao.findParentMenu();
            for (Menu menu : parentMenuList) {
                //查询变化区间内的父菜单
                if (menu.getPriority() <= priorityInParam && menu.getPriority() > priorityInDB) {
                    //set priority
                    menu.setPriority(menu.getPriority() - 1);
                    //set path
                    menu.setPath(String.valueOf(menu.getPriority() + 1));
                    //查询父菜单对应的所有子菜单
                    List<Menu> childrenMenuList = menuDao.findChildrenMenuByParentMenuId(menu.getId());
                    for (Menu childrenMenu : childrenMenuList) {
                        // set path
                        childrenMenu.setPath("/" + String.valueOf(menu.getPriority() + 1) + "-" + String.valueOf(childrenMenu.getPriority()));
                    }
                }
            }
            List<Menu> childrenMenus = menuDao.findChildrenMenuByParentMenuId(parentMenu.getId());
            for (Menu childrenMenu : childrenMenus) {
                // set path
                childrenMenu.setPath("/" + String.valueOf(parentMenu.getPriority() + 1) + "-" + String.valueOf(childrenMenu.getPriority()));
            }
            //set path
            parentMenu.setPath(String.valueOf(parentMenu.getPriority() + 1));
            //edit
            menuDao.edit(parentMenu);
        }

    }

    //编辑子类
    @Override
    @Transactional
    public void editChildren(Menu childrenMenu, int priorityInDB) {

        int priorityInParam = childrenMenu.getPriority();
        //2. 判断优先级是否发生变化
        if (priorityInDB == priorityInParam) {//未发生变化
            //edit
            menuDao.edit(childrenMenu);
        } else if (priorityInDB > priorityInParam) {//优先级变小
            //查找对应父菜单
            Menu parentMenu = menuDao.findMenuById(childrenMenu.getParentMenuId());
            //查询父菜单对应的所有子菜单
            List<Menu> childrenMenuList = menuDao.findChildrenMenuByParentMenuId(parentMenu.getId());
            for (Menu menu : childrenMenuList) {
                //查询变化区间内的子菜单
                if (menu.getPriority() >= priorityInParam && menu.getPriority() < priorityInDB) {
                    //set priority
                    menu.setPriority(menu.getPriority() + 1);
                    //set path
                    menu.setPath("/" + String.valueOf(parentMenu.getPriority() + 1) + "-" + String.valueOf(menu.getPriority()));
                }
            }
            //edit
            menuDao.edit(childrenMenu);
        } else {//优先级变大
            //查找对应父菜单
            Menu parentMenu = menuDao.findMenuById(childrenMenu.getParentMenuId());
            //查询父菜单对应的所有子菜单
            List<Menu> childrenMenuList = menuDao.findChildrenMenuByParentMenuId(parentMenu.getId());
            for (Menu menu : childrenMenuList) {
                //查询变化区间内的子菜单
                if (menu.getPriority() <= priorityInParam && menu.getPriority() > priorityInDB) {
                    //set priority
                    menu.setPriority(menu.getPriority() - 1);
                    //set path
                    menu.setPath("/" + String.valueOf(parentMenu.getPriority() + 1) + "-" + String.valueOf(menu.getPriority()));
                }
            }
            //edit
            menuDao.edit(childrenMenu);
        }
    }

}

